/**
 * 
 */
package es.twentymobile.mule.modules.jpa.dsl;

import javax.persistence.EntityManager;

import com.mysema.query.DefaultQueryMetadata;
import com.mysema.query.QueryMetadata;
import com.mysema.query.jpa.HQLTemplates;
import com.mysema.query.jpa.JPQLTemplates;
import com.mysema.query.jpa.impl.AbstractJPAQuery;
import com.mysema.query.jpa.impl.JPAProvider;

/**
 * @author alvarezjm
 * 
 */
public final class CustomJPAQuery extends AbstractJPAQuery<CustomJPAQuery> {

	/**
	 * Creates a new detached query The query can be attached via the clone
	 * method
	 */
	public CustomJPAQuery() {
		super(null, HQLTemplates.DEFAULT, new DefaultQueryMetadata());
	}

	/**
	 * Creates a new EntityManager bound query
	 * 
	 * @param em
	 */
	public CustomJPAQuery(EntityManager em) {
		super(em, JPAProvider.getTemplates(em), new DefaultQueryMetadata());
	}

	/**
	 * Creates a new EntityManager bound query
	 * 
	 * @param em
	 */
	public CustomJPAQuery(EntityManager em, QueryMetadata metadata) {
		super(em, JPAProvider.getTemplates(em), metadata);
	}

	/**
	 * Creates a new query
	 * 
	 * @param em
	 * @param patterns
	 */
	public CustomJPAQuery(EntityManager em, JPQLTemplates patterns) {
		super(em, patterns, new DefaultQueryMetadata());
	}

	/**
	 * Creates a new query
	 * 
	 * @param em
	 * @param templates
	 * @param metadata
	 */
	public CustomJPAQuery(EntityManager em, JPQLTemplates templates, QueryMetadata metadata) {
		super(em, templates, metadata);
	}

	/**
	 * Clone the state of this query to a new JPAQuery instance with the given
	 * EntityManager
	 * 
	 * @param entityManager
	 * @return
	 */
	public CustomJPAQuery clone(EntityManager entityManager) {
		CustomJPAQuery q = new CustomJPAQuery(entityManager, getTemplates(), getMetadata().clone());
		q.factoryExpressionUsed = factoryExpressionUsed;
		q.flushMode = flushMode;
		q.hints.putAll(hints);
		q.lockMode = lockMode;
		return q;
	}

	@Override
	protected String buildQueryString(boolean forCountRow) {
		if (getQueryMixin().getMetadata().getJoins().isEmpty()) {
			throw new IllegalArgumentException("No joins given");
		}
		CustomJPQLSerializer serializer = new CustomJPQLSerializer(getTemplates(), entityManager);
		serializer.serialize(getQueryMixin().getMetadata(), forCountRow, null);
		setConstants(serializer.getConstantToLabel());
		return serializer.toString();
	}

}
